#include "dicthandler.h"

#include <QDebug>
#include <algorithm>

// 静态成员初始化
DictHandler* DictHandler::m_instance = nullptr;
QMutex DictHandler::m_instanceMutex;

DictHandler::DictHandler(QObject *parent) : QObject(parent)
{
    // 初始化用户词典实例并监听变更
    m_userDict = UserDict::getInstance();
    connect(m_userDict, &UserDict::dictChanged, this, &DictHandler::onUserDictChanged);

    // 从ConfigManager加载默认系统词典路径
    ConfigManager* config = ConfigManager::getInstance();
    QString defaultDictPath = config->getValue(
        InputMethodGroup, 
        "BaseDictPath", 
        "dictionary/dict_files/pinyin_base_dict.json"
    ).toString();
    bool isEncrypted = config->getValue(
        InputMethodGroup, 
        "BaseDictEncrypted", 
        false
    ).toBool();

    // 3. 加载系统词典（失败时降级为内置默认词典）
    if (!loadSystemDict(defaultDictPath, isEncrypted)) {
        qCritical() << "[DictHandler] 默认系统词典加载失败，路径：" << defaultDictPath;
        loadSystemDict(":/dictionary/default_dict.json", false);
    }
}

DictHandler* DictHandler::getInstance(QObject *parent)
{
    if (!m_instance) {
        QMutexLocker locker(&m_instanceMutex);
        if (!m_instance) {
            m_instance = new DictHandler(parent);
        }
    }
    return m_instance;
}

DictHandler::~DictHandler()
{
    clearCache();
    qInfo() << "[DictHandler] 析构完成，已清空缓存";
}

// 加载系统词典（支持加密）
bool DictHandler::loadSystemDict(const QString& jsonPath, bool encrypted)
{
    QFile dictFile(jsonPath);
    if (!dictFile.open(QIODevice::ReadOnly)) {
        qWarning() << "[DictHandler] 词典文件打开失败：" << jsonPath << "，错误：" << dictFile.errorString();
        emit systemDictLoaded(false);
        return false;
    }

    // 读取并解密（如需）
    QByteArray dictData = dictFile.readAll();
    dictFile.close();
    if (encrypted) {
        QByteArray key = EncryptUtil::generateKey();
        QString decryptedStr = EncryptUtil::decryptString(dictData, key);
        dictData = decryptedStr.toUtf8();
        if (dictData.isEmpty()) {
            qWarning() << "[DictHandler] 词典解密失败：" << jsonPath;
            emit systemDictLoaded(false);
            return false;
        }
    }

    // 解析JSON词典
    QJsonParseError parseErr;
    QJsonDocument dictDoc = QJsonDocument::fromJson(dictData, &parseErr);
    if (parseErr.error != QJsonParseError::NoError) {
        qWarning() << "[DictHandler] 词典JSON解析失败：" << parseErr.errorString();
        emit systemDictLoaded(false);
        return false;
    }

    // 写入系统词典存储
    QMutexLocker locker(&m_dictMutex);
    m_systemDict.clear();
    m_systemWordCount = 0;
    QJsonObject root = dictDoc.object();

    for (auto it = root.begin(); it != root.end(); ++it) {
        QString pinyin = it.key();
        QJsonArray wordArr = it.value().toArray();
        QVector<PinyinCandidate> candidates;

        for (const QJsonValue& val : wordArr) {
            QString word = val.toString();
            if (word.isEmpty()) continue;
            // 系统词默认词频10（低于用户词初始词频，确保用户词优先）
            candidates.append({word, 10, pinyin, false});
            m_systemWordCount++;
        }

        if (!candidates.isEmpty()) {
            m_systemDict[pinyin] = candidates;
        }
    }

    // 加载完成后清空缓存
    clearCache();
    qInfo() << "[DictHandler] 系统词典加载成功：路径=" << jsonPath 
            << "，拼音条目数=" << m_systemDict.size() 
            << "，总词数=" << m_systemWordCount;
    emit systemDictLoaded(true);
    return true;
}

// 合并系统词与用户词（核心逻辑）
QVector<PinyinCandidate> DictHandler::mergeCandidates(
    const QVector<PinyinCandidate>& systemCandidates,
    const QVector<PinyinCandidate>& userCandidates
) {
    QMap<QString, PinyinCandidate> mergedMap;

    // 先添加系统词（后续用户词覆盖同词语）
    for (const auto& cand : systemCandidates) {
        mergedMap[cand.text] = cand;
    }

    // 再添加用户词（覆盖系统词，实现优先级）
    for (const auto& cand : userCandidates) {
        mergedMap[cand.text] = cand;
    }

    // 转为Vector并按词频降序排序
    QVector<PinyinCandidate> mergedList;
    for (const auto& cand : mergedMap) {
        mergedList.append(cand);
    }
    std::sort(mergedList.begin(), mergedList.end(), [](const PinyinCandidate& a, const PinyinCandidate& b) {
        return a.frequency > b.frequency;
    });

    return mergedList;
}

// 统一查询接口：合并系统+用户词典
QVector<PinyinCandidate> DictHandler::queryCandidates(const QString& pinyin)
{
    if (pinyin.isEmpty()) return {};

    // 优先查询缓存
    QMutexLocker cacheLocker(&m_cacheMutex);
    if (m_queryCache.contains(pinyin)) {
        return m_queryCache[pinyin];
    }
    cacheLocker.unlock();

    // 分别查询系统/用户词典
    QVector<PinyinCandidate> systemCands = querySystemDict(pinyin);
    QVector<PinyinCandidate> userCands = queryUserDict(pinyin);

    // 合并结果并更新缓存
    QVector<PinyinCandidate> mergedCands = mergeCandidates(systemCands, userCands);
    cacheLocker.relock();
    m_queryCache[pinyin] = mergedCands;

    return mergedCands;
}

// 查询系统词典（支持前缀模糊匹配）
QVector<PinyinCandidate> DictHandler::querySystemDict(const QString& pinyin)
{
    QMutexLocker locker(&m_dictMutex);
    // 精确匹配优先
    if (m_systemDict.contains(pinyin)) {
        return m_systemDict[pinyin];
    }

    // 前缀模糊匹配（如"ch"匹配"chi"、"chang"）
    QVector<PinyinCandidate> prefixCands;
    for (auto it = m_systemDict.begin(); it != m_systemDict.end(); ++it) {
        if (it.key().startsWith(pinyin)) {
            prefixCands.append(it.value());
        }
    }
    return prefixCands;
}

// 查询用户词典（委托给UserDict）
QVector<PinyinCandidate> DictHandler::queryUserDict(const QString& pinyin)
{
    if (!m_userDict || !m_userDict->isConnected()) {
        return {};
    }
    return m_userDict->queryWords(pinyin);
}

// 清空查询缓存
void DictHandler::clearCache()
{
    QMutexLocker locker(&m_cacheMutex);
    m_queryCache.clear();
    qInfo() << "[DictHandler] 查询缓存已清空";
}

// 用户词典变更时刷新缓存
void DictHandler::onUserDictChanged()
{
    clearCache();
    emit dictUpdated();
    qInfo() << "[DictHandler] 用户词典更新，已同步清空缓存";
}